[gcc] Replace rsp/rbp lea base with esp/ebp This is yet another fix for POINTERS_EXTEND_UNSIGNED > 0 problem of keeping high part of rsp/rbp. In addition, minor fix for previous change - do not assert if writing rsp/rbp into memory (probably spill)? Test (-O1) must return 0 but returns high part of rsp without the fix: struct StringRef { const char *Data; unsigned Length; }; // Prevent inlining with 'weak' attribute int print_size(struct StringRef Data) __attribute__((weak)); int print_size(struct StringRef Data) { return Data.Length; } int main() { char str[6]; // NEEDED! struct StringRef s; s.Data = str + 3; // NEEDED! s.Length = 0; return print_size(s); } BUG=http://code.google.com/p/nativeclient/issues/detail?id=1304 TEST=see above Review URL: http://codereview.chromium.org/6271009 
diff --git a/gcc/gcc/config/i386/i386-protos.h b/gcc/gcc/config/i386/i386-protos.h index 3cd5368..a79d1af 100644 --- a/gcc/gcc/config/i386/i386-protos.h +++ b/gcc/gcc/config/i386/i386-protos.h 
@@ -263,6 +263,7 @@    extern int lea_match_address_operand (rtx, enum machine_mode);  extern int ix86_decompose_address (rtx, struct ix86_address *); +extern int ix86_lea_decompose_address (rtx, struct ix86_address *);  extern int memory_address_length (rtx addr);  extern void x86_output_aligned_bss (FILE *, tree, const char *,  unsigned HOST_WIDE_INT, int); 
diff --git a/gcc/gcc/config/i386/i386.c b/gcc/gcc/config/i386/i386.c index 82802ef..7687ca0 100644 --- a/gcc/gcc/config/i386/i386.c +++ b/gcc/gcc/config/i386/i386.c 
@@ -1818,7 +1818,6 @@  static bool ix86_valid_target_attribute_inner_p (tree, char *[]);  static bool ix86_can_inline_p (tree, tree);  static void ix86_set_current_function (tree); -static int ix86_lea_decompose_address (rtx, struct ix86_address *);  static int legitimate_address_parts_p (const struct ix86_address *, int);  static void print_operand_address_parts (FILE *, const struct ix86_address *);   @@ -8796,7 +8795,7 @@  instruction.  WARNING: This is a copy-paste of the original ix86_decompose_address. */   -static int +int  ix86_lea_decompose_address (rtx addr, struct ix86_address *out)  {  rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX; 
diff --git a/gcc/gcc/config/i386/i386.md b/gcc/gcc/config/i386/i386.md index 93223b2..59c02d0 100644 --- a/gcc/gcc/config/i386/i386.md +++ b/gcc/gcc/config/i386/i386.md 
@@ -2435,21 +2435,19 @@  if (!(REG_P (operands[1]) && REGNO (operands[1]) == SP_REG))  return "naclrestbp\t{%k1, %%r15|%%r15, %k1}";   - /* Get RSP. */ + /* Get RSP. + This also truncated RSP when spilling? it to MEM, which should + still work as fill will use naclrestsp. */  if (REG_P (operands[1]) && REGNO (operands[1]) == SP_REG) - { - gcc_assert (REG_P (operands[0])); - if (REGNO (operands[0]) != BP_REG) -	return "mov{l}\t{%k1, %k0|%k0, %k1}"; - } + if (!(REG_P (operands[0]) && REGNO (operands[0]) == BP_REG)) + return "mov{l}\t{%k1, %k0|%k0, %k1}";   - /* Get RBP. */ + /* Get RBP. + This also truncated RBP when spilling? it to MEM, which should + still work as fill will use naclrestbp. */  if (REG_P (operands[1]) && REGNO (operands[1]) == BP_REG) - { - gcc_assert (REG_P (operands[0])); - if (REGNO (operands[0]) != SP_REG) -	return "mov{l}\t{%k1, %k0|%k0, %k1}"; - } + if (!(REG_P (operands[0]) && REGNO (operands[0]) == SP_REG)) + return "mov{l}\t{%k1, %k0|%k0, %k1}"; 	}  return "mov{q}\t{%1, %0|%0, %1}";  } @@ -6009,7 +6007,23 @@  [(set (match_operand:DI 0 "register_operand" "=r") 	(match_operand:DI 1 "lea_address_operand" "T"))]  "TARGET_64BIT" - "lea{q}\t{%Z1, %0|%0, %Z1}" +{ + if (TARGET_NACL) + { + struct ix86_address parts; + int ok; + + ok = ix86_lea_decompose_address (operands[1], &parts); + gcc_assert (ok); + + if (parts.base) +	{ + if (REGNO (parts.base) == SP_REG || REGNO (parts.base) == BP_REG) + return "lea{l}\t{%Z1, %k0|%k0, %Z1}"; +	} + } + return "lea{q}\t{%Z1, %0|%0, %Z1}"; +}  [(set_attr "type" "lea")  (set_attr "mode" "DI")])